
const AbstractBaseRpcApi=require("ming_node/plugins/BaseRpcApi/AbstractBaseRpcApi");

class RedisDb{
    constructor({tableName,redisClient}) {
        this.tableName=tableName;
        this.redisClient=redisClient;
       // this.dataList=[];
    }
    get dataList(){
        return new Promise((async (resolve, reject) => {
            let datalistJsonStr=await this.redisClient.get(this.tableName);
            if(datalistJsonStr==null){
                resolve([]) ;
                return;
            }
            let dataList= JSON.parse(datalistJsonStr)
            resolve(dataList) ;
        }))

   }

     set dataList(datalist){
        new Promise(((resolve, reject) => {
            let datalistJsonStr= JSON.stringify(datalist);
            this.redisClient.set(this.tableName,datalistJsonStr)
            resolve(datalist);
        }))
    }
    /**
     * 单个加
     * @param obj
     * @returns {Promise<*>}
     */
    async add(obj){
        obj.id = M.randomStr();
        let dataList=await this.dataList;
        this.dataList=[...dataList,obj];
        return obj;
    }

    async update(obj){
        let dataList=await this.dataList;
        for (let i = 0; i < dataList.length; i++) {
            if (dataList[i].id == obj.id) {
                dataList[i]=obj;
                this.dataList=dataList;
                return
            }
        }
    }

   async listAll(caseObj){
        let o_keys = Object.keys(caseObj);
        if (caseObj && o_keys.length>0) {
            let r_list = [];
            let o_vals = Object.values(caseObj);
            var d =await this.dataList;
            for (let i = 0; i < d.length; i++) {
                let s=0;
                for (let j=0;j<o_keys.length;j++){
                    if (d[i][o_keys[j]] != o_vals[j]) {
                        break
                    }
                    s++;
                }
                if(s==o_keys.length){
                    r_list.push(d[i]);
                }
            }
            return r_list;
        } else {
            return this.dataList;
        }
    }


   async listByPage(startPage=0, limit=10, caseObj) {
        startPage=Number.parseInt(startPage);
        limit=Number.parseInt(limit);
        if (startPage <= 0) startPage = 1;
        let rows;
        if (caseObj) {
            rows =await this.listAll(caseObj);
        } else {
            rows =await this.listAll();
        }
        let total = rows.length;
        rows=JSON.parse(JSON.stringify(rows))
        rows = rows.splice((startPage - 1) * limit, limit)
        return {rows, total}
    }


    async deleteAll(o) {
        if (o) {
            let r_list = [];
            let o_keys = Object.keys(o);
            let o_vals = Object.values(o)
            var d =await this.dataList;
            let delete_index=[]
            for (let i = 0; i < d.length; i++) {
                let s=0;
                for (let j=0;j<o_keys.length;j++){
                    if (d[i][o_keys[j]] != o_vals[j]) {
                        break
                    }
                    s++;
                }
                if(s==o_keys.length){
                    delete_index.push(i)
                }
            }
            for (let i = 0; i < d.length; i++) {
                if(!delete_index.includes(i)){
                    r_list.push(d[i])
                }
            }
            this.dataList=r_list;
            return delete_index.length;
        } else {
            this.dataList=[];
            return 0;
        }
    }

    async getById(id) {
        var d =await this.dataList;
        for (let i = 0; i < d.length; i++) {
            if(d[i].id==id){
                return d[i];
            }
        }
        return null;
    }

    async deleteById(id) {
        var d =await this.dataList;
        for (let i = 0; i < d.length; i++) {
            if(d[i].id==id){
                d.splice(i, 1);
                this.dataList=d;
                return id;
            }
        }
        return 0;
    }
}


class RedisSetDb{
    constructor({tableName,redisClient}) {
        this.tableName=tableName;
        this.redisClient=redisClient;
        // this.dataList=[];
    }
    get dataList(){
        return new Promise((async (resolve, reject) => {
            let datalistJsonStr=await this.redisClient.smembers(this.tableName);
            if(datalistJsonStr==null){
                resolve([]) ;
                return;
            }
            let dataList= JSON.parse(datalistJsonStr)
            resolve(dataList) ;
        }))

    }

    set dataList(datalist){
        new Promise(((resolve, reject) => {
            let datalistJsonStr= JSON.stringify(datalist);
            this.redisClient.set(this.tableName,datalistJsonStr)
            resolve(datalist);
        }))
    }
    /**
     * 单个加
     * @param obj
     * @returns {Promise<*>}
     */
    async add(obj){
        obj.id = M.randomStr();
        let dataList=await this.dataList;
        this.dataList=[...dataList,obj];
        return obj;
    }

    async update(obj){
        let dataList=await this.dataList;
        for (let i = 0; i < dataList.length; i++) {
            if (dataList[i].id == obj.id) {
                dataList[i]=obj;
                this.dataList=dataList;
                return
            }
        }
    }

    async listAll(caseObj){
        let o_keys = Object.keys(caseObj);
        if (caseObj && o_keys.length>0) {
            let r_list = [];
            let o_vals = Object.values(caseObj);
            var d =await this.dataList;
            for (let i = 0; i < d.length; i++) {
                let s=0;
                for (let j=0;j<o_keys.length;j++){
                    if (d[i][o_keys[j]] != o_vals[j]) {
                        break
                    }
                    s++;
                }
                if(s==o_keys.length){
                    r_list.push(d[i]);
                }
            }
            return r_list;
        } else {
            return this.dataList;
        }
    }


    async listByPage(startPage=0, limit=10, caseObj) {
        startPage=Number.parseInt(startPage);
        limit=Number.parseInt(limit);
        if (startPage <= 0) startPage = 1;
        let rows;
        if (caseObj) {
            rows =await this.listAll(caseObj);
        } else {
            rows =await this.listAll();
        }
        let total = rows.length;
        rows=JSON.parse(JSON.stringify(rows))
        rows = rows.splice((startPage - 1) * limit, limit)
        return {rows, total}
    }


    async deleteAll(o) {
        if (o) {
            let r_list = [];
            let o_keys = Object.keys(o);
            let o_vals = Object.values(o)
            var d =await this.dataList;
            let delete_index=[]
            for (let i = 0; i < d.length; i++) {
                let s=0;
                for (let j=0;j<o_keys.length;j++){
                    if (d[i][o_keys[j]] != o_vals[j]) {
                        break
                    }
                    s++;
                }
                if(s==o_keys.length){
                    delete_index.push(i)
                }
            }
            for (let i = 0; i < d.length; i++) {
                if(!delete_index.includes(i)){
                    r_list.push(d[i])
                }
            }
            this.dataList=r_list;
            return delete_index.length;
        } else {
            this.dataList=[];
            return 0;
        }
    }

    async getById(id) {
        var d =await this.dataList;
        for (let i = 0; i < d.length; i++) {
            if(d[i].id==id){
                return d[i];
            }
        }
        return null;
    }

    async deleteById(id) {
        var d =await this.dataList;
        for (let i = 0; i < d.length; i++) {
            if(d[i].id==id){
                d.splice(i, 1);
                this.dataList=d;
                return id;
            }
        }
        return 0;
    }
}



class RedisBaseRpcApi extends AbstractBaseRpcApi{

    constructor(props) {
        super(props);
        this.redisDb=props.redisDb;
    }
    async add(obj){
        let r= this.redisDb.add(obj);
        return r;
    }

    async delete(obj){
        let r= this.redisDb.deleteAll(obj);
        return r;
    }

    async getById(id){
        let r=this.redisDb.getById(id);
        return r;
    }

    async list({page,num,queryCase}){
        let r= this.redisDb.listByPage(page,num,queryCase);
        return r;
    }

    async listAll(obj){
        let r= this.redisDb.listAll(obj);
        return r;
    }

    async update(obj){
        let r= this.redisDb.update(obj);
        return r;
    }

    async getChildenList(id,caseObj){
        let r= this.redisDb.listAll({parent_id:id,...caseObj});
        return r;
    }
}


module.exports ={RedisDb,RedisBaseRpcApi} ;